#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>

#define X86_DEBUG 1

#ifdef X86_DEBUG
#define INT32 int
#define ARP_TABLE "./arp"
#define DHCP_LEASE_FILE "./dhcp.leases"
#else
#define ARP_TABLE "/proc/net/arp"
#define DHCP_LEASE_FILE "/tmp/dnsmasq.leases"
#endif

#define LAN1 "br0"
#define LAN2 "br1"

typedef struct _host{
	char ip[64];
	char source[64];
	char remain[64];
	char mac[64];
	char l2inf[64];
	char vid[64];
	char cid[64];
	char uid[64];
	char host[64];
	char inftype[64];
	char active[64];
}HOST_T;

typedef struct _hosts{
	int num;
	int old_num;
	HOST_T *host;
}HOSTS_T;

static HOSTS_T lan1_hosts={0, 0, NULL};
static HOSTS_T lan2_hosts={0, 0, NULL};

INT32 hosts_get_host_number(char *inf)
{
	FILE *fp = NULL;
	char buff[512] = {0};
	char ip[64] = {0};
	char hw_type[64] = {0};
	char flags[64] = {0};
	char hw_addr[64] = {0};
	char mask[64] = {0};
	char device[64] = {0};
	int read_num = 0;
	int host_num = 0;

	fp = fopen(ARP_TABLE, "r");
	if(fp == NULL)
		return 0;

	while(fgets(buff, sizeof(buff), fp)){
		memset(ip, sizeof(ip), 0);
		memset(hw_addr, sizeof(hw_addr), 0);
		memset(device, sizeof(device), 0);
		read_num = sscanf(buff, "%[0-9,.]%*[ ]%s%*[ ]%s%*[ ]%s%*[ ]%s%*[ ]%s*", ip, hw_type, flags, hw_addr, mask, device);
		if( read_num == 6 && !strcmp(device, inf)){
			host_num++;
		}
	}
	fclose(fp);
	
	return host_num;
}

void hosts_init(HOSTS_T *hosts, char *inf)
{
	int host_size = 0;
	int number = 0;

	if(hosts->host){
		free(hosts->host);
		hosts->host = NULL;
	}

	hosts->old_num = hosts->num;
	hosts->num = hosts_get_host_number(inf);
	host_size = sizeof(HOST_T)*hosts->num;
	hosts->host = (HOST_T *)malloc(host_size);
	memset(hosts->host, 0, host_size);
}

INT32 hosts_load_arp_table(HOSTS_T *hosts, char *inf)
{
	FILE *fp = NULL;
	char buff[512] = {0};
	char ip[64] = {0};
	char hw_type[64] = {0};
	char flags[64] = {0};
	char hw_addr[64] = {0};
	char mask[64] = {0};
	char device[64] = {0};
	int read_num = 0;
	int idx = 0;

	fp = fopen(ARP_TABLE, "r");
	if(fp == NULL)
		return 0;

	while(fgets(buff, sizeof(buff), fp)){
		memset(ip, sizeof(ip), 0);
		memset(hw_addr, sizeof(hw_addr), 0);
		memset(device, sizeof(device), 0);
		read_num = sscanf(buff, "%[0-9,.]%*[ ]%s%*[ ]%s%*[ ]%s%*[ ]%s%*[ ]%s*", ip, hw_type, flags, hw_addr, mask, device);
		if( read_num == 6 && !strcmp(device, inf)){
			printf("idx[%d] ip[%s] hw_type[%s] flags[%s] hw_addr[%s] mask[%s] device[%s]\n", idx, ip, hw_type, flags, hw_addr, mask, device);
			strcpy(hosts->host[idx].ip, ip);
			strcpy(hosts->host[idx].source, "Static");
			strcpy(hosts->host[idx].remain, "0");
			strcpy(hosts->host[idx].mac, hw_addr);
			strcpy(hosts->host[idx].l2inf, "");
			strcpy(hosts->host[idx].vid, "");
			strcpy(hosts->host[idx].cid, "");
			strcpy(hosts->host[idx].uid, "");
			strcpy(hosts->host[idx].host, "");
			strcpy(hosts->host[idx].inftype, "");
			strcpy(hosts->host[idx].active, "1");
			idx++;
		}
	}
	fclose(fp);
	
	return 0;
}

INT32 hosts_load_dhcp_leases(HOSTS_T *hosts)
{
	FILE *fp = NULL;
	char buff[512] = {0};
	char remain[64] = {0};
	char mac[64] = {0};
	char ip[64] = {0};
	char host[64] = {0};
	int read_num = 0;
	int idx = 0;
	INT32 ret = -1;

	fp = fopen(DHCP_LEASE_FILE, "r");
	if(fp == NULL)
		return ret;

	while(fgets(buff, sizeof(buff), fp)){
		read_num = sscanf(buff, "%s %s %s %s *", remain, mac, ip, host);
		//printf("read_num = %d\n", read_num);
		if( read_num == 4){
			for(idx = 0; idx < hosts->num; idx++){
				if(!strcmp(hosts->host[idx].ip, ip)){
					//printf("dbg---> remain=[%s], mac=[%s], ip=[%s], host=[%s]\n", remain, mac, ip, host);
					strcpy(hosts->host[idx].remain, remain);
					strcpy(hosts->host[idx].host, host);
					strcpy(hosts->host[idx].source, "DHCP");
					strcpy(hosts->host[idx].active, "1");
				}
			}
		}
	}
	fclose(fp);
	
	return ret;
}

void hosts_print(HOSTS_T *hosts)
{
	int i = 1;
	char value[64] = {0};

	printf("----- host print -----");
	printf("host num = [%d]\n", hosts->num);
	for(i = 0; i < hosts->num; i++){
		printf("i = [%d], ip=[%s] mac=[%s] host=[%s] source=[%s] active=[%s] remain=[%s]\n", 
			i, hosts->host[i].ip, hosts->host[i].mac, hosts->host[i].host, hosts->host[i].source, hosts->host[i].active, hosts->host[i].remain);
	}
}

INT32 hosts_update_data_model()
{
#if 0
	if(lan1_hosts.old_num > lan1_hosts.num)
		tr69c_delObjInstance("InternetGatewayDevice.LANDevice.1.Hosts.Host.", lan1_hosts.num + 1, lan1_hosts.old_num);
	if(lan1_hosts.old_num < lan1_hosts.num)
		tr69c_addObjInstance("InternetGatewayDevice.LANDevice.1.Hosts.Host.", lan1_hosts.num - lan1_hosts.old_num);
	if(lan2_hosts.old_num > lan2_hosts.num)
		tr69c_delObjInstance("InternetGatewayDevice.LANDevice.2.Hosts.Host.", lan2_hosts.num + 1, lan2_hosts.old_num);
	if(lan2_hosts.old_num < lan2_hosts.num)
		tr69c_addObjInstance("InternetGatewayDevice.LANDevice.2.Hosts.Host.", lan2_hosts.num - lan2_hosts.old_num);
#endif
}

INT32 hosts_update()
{
	int number = 0;

	hosts_init(&lan1_hosts, LAN1);
	hosts_load_arp_table(&lan1_hosts, LAN1);
	hosts_load_dhcp_leases(&lan1_hosts);

	hosts_init(&lan2_hosts, LAN2);
	hosts_load_arp_table(&lan2_hosts, LAN2);
	hosts_load_dhcp_leases(&lan2_hosts);

	hosts_update_data_model();
}

int main(int argc, char *argv[])
{
	int index;
	int lan1_num = 0, lan2_num = 0;

	hosts_update();
	hosts_print(&lan1_hosts);
	hosts_print(&lan2_hosts);

	return 0;
}
